/**  
 * All rights Reserved, Designed By www.richfit.com
 * @Title:  DataSourceSwitchAspect.java   
 * @Package cn.eonshine.base.config.mulitdb   
 * @Description:    TODO
 * @author: lanjf2000
 * @date:   2018-10-15 18:59:00
 * @version V1.0 
 * @Copyright: 2018 www.richfit.com Inc. All rights reserved. 
 */
package cn.eonshine.base.config.mulitdb.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import cn.eonshine.base.config.mulitdb.DataSourceContextHolder;
import cn.eonshine.base.config.mulitdb.DataSourceEnum;
import lombok.extern.slf4j.Slf4j;

/**   
 * @ClassName:  DataSourceSwitchAspect   
 * @Description:TODO
 * @author: lanjf2000
 * @date:   2018-10-15 18:59:00
 *     
 * @Copyright: 2018 www.richfit.com Inc. All rights reserved. 
 */
@Component
@Aspect
@Order(-100) //这是为了保证AOP在事务注解之前生效,Order的值越小,优先级越高
@Slf4j
public class DataSourceSwitchAspect {
	
	private static final String LSMS = "cn.eonshine.cuba.lsms.modular";
	private static final String INF = "cn.eonshine.cuba.inf.modular";
	private static final String SECURITY = "cn.eonshine.cuba.securitybackup.modular";
	
	@Pointcut("execution(* "+LSMS+"..*.*(..))")
    private void db1Aspect() {
    }

    @Pointcut("execution(* "+INF+"..*.*(..))")
    private void db2Aspect() {
    }
    
    @Pointcut("execution(* "+SECURITY+"..*.*(..))")
    private void db3Aspect() {
    }

    @Before( "db1Aspect()" )
    public void db1(JoinPoint point) {
        log.info("Change to db1 (lsms) DataSource..."+point.getTarget().getClass().getName());
//        DataSourceContextHolder.setDataSource(DataSourceEnum.DB1.getValue());
        changeDB(point.getTarget().getClass().getName(), DataSourceEnum.DB1.getValue());
    }
    
    @Before("db2Aspect()" )
    public void db2 (JoinPoint point) {
        log.info("Change to db2 (inf) DataSource..."+point.getTarget().getClass().getName());
//        DataSourceContextHolder.setDataSource(DataSourceEnum.DB2.getValue());
        changeDB(point.getTarget().getClass().getName(), DataSourceEnum.DB2.getValue());
    }
    
    @Before("db3Aspect()" )
    public void db3 (JoinPoint point) {
        log.info("Change to db3 (securitybackup) DataSource..."+point.getTarget().getClass().getName());
//        DataSourceContextHolder.setDataSource(DataSourceEnum.DB3.getValue());
        changeDB(point.getTarget().getClass().getName(), DataSourceEnum.DB3.getValue());
    }
    
    public void changeDB(String name, String defaultName) {
    	if(name.startsWith(LSMS)) {
    		log.info("Final Change to db1 (lsms) DataSource..."+name);
    		DataSourceContextHolder.setDataSource(DataSourceEnum.DB1.getValue());
    	}else if(name.startsWith(INF)) {
    		log.info("Final Change to db2 (inf) DataSource..."+name);
    		DataSourceContextHolder.setDataSource(DataSourceEnum.DB2.getValue());
    	}else if(name.startsWith(SECURITY)) {
    		log.info("Final Change to db3 (securitybackup) DataSource..."+name);
    		DataSourceContextHolder.setDataSource(DataSourceEnum.DB3.getValue());
    	}else {
    		log.info("Final Change to db (default) DataSource..."+name);
    		DataSourceContextHolder.setDataSource(defaultName);
    	}
    }
    
    
//    @After("db1Aspect()")
//    public void restoreDataSource1() {
//    	log.info("clear db1 (lsms) DataSource...");
//    	DataSourceContextHolder.clear();
//    }
//    
//    @After("db2Aspect()")
//    public void restoreDataSource2() {
//    	log.info("clear db2 (inf) DataSource...");
//    	DataSourceContextHolder.clear();
//    }
    
//
//    /**
//     * 添加注解方式,如果有注解优先注解,没有则按传过来的数据源配置
//     * @param joinPoint
//     * @param dbTypeEnum
//     */
//    private void setDataSource(JoinPoint joinPoint, DataSourceEnum dbTypeEnum) {
//        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
//        DataSourceSwitch dataSourceSwitch = methodSignature.getMethod().getAnnotation(DataSourceSwitch.class);
//        if (Objects.isNull(dataSourceSwitch) || Objects.isNull(dataSourceSwitch.value())) {
//        	DataSourceContextHolder.setDataSource(dbTypeEnum.getValue());
//        }else{
//            log.info("Data Source set :"+dataSourceSwitch.value());
//            switch (dataSourceSwitch.value().getValue()) {
//                case DataSourceFlag.db1:
//                	DataSourceContextHolder.setDataSource(DataSourceEnum.DB1.getValue());
//                    break;
//                case DataSourceFlag.db2:
//                	DataSourceContextHolder.setDataSource(DataSourceEnum.DB2.getValue());
//                    break;
//                default:
//                	DataSourceContextHolder.setDataSource(dbTypeEnum.getValue());
//            }
//        }
//    }
}
